package com.sm.chatinputlibrary;

import android.app.Activity;
import android.content.Context;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;

import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.scorpio.baselibrary.ScreenAdapterTools;
import com.scorpio.baselibrary.utils.CommonUtils;
import com.sm.chatinputlibrary.utils.RecorderUtil;
import java.io.File;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * created by zhud on 2019/4/11
 */
public class AudioRecorderView extends AppCompatTextView implements RecorderUtil.RecorderProcessListener {
    private final String TAG = AudioRecorderView.class.getSimpleName();
    private ViewGroup mDecorView;
    private View mAudioProgressLayout;
    private RecorderUtil mAudioRecorder;
    private AudioProgressView mAudioProgressView;
    private long recorderMinTime = 2;
    //最大录音时间
    private long recorderMaxTime = 60;
    private View audio_cancel_layout, audio_send_layout;
    private OnAudioRecorderEventListener onAudioRecorderEventListener;
    public static final int RESULT_OK = 0;//录音成功
    public static final int RESULT_CANCEL = 1;//取消
    public static final int RESULT_OUT_TIME = -1;//超时
    public static final int RESULT_OUT_ERROR = -2;//错误
    public static final int RESULT_TOO_SHORT_ERROR = -3;//录制过短

    @IntDef({RESULT_OK, RESULT_CANCEL, RESULT_OUT_TIME, RESULT_OUT_ERROR, RESULT_TOO_SHORT_ERROR})
    @Retention(RetentionPolicy.SOURCE)
    public @interface AudioRecorderResult {
    }

    public AudioRecorderView(Context context) {
        this(context, null);
    }

    public AudioRecorderView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AudioRecorderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mDecorView = (ViewGroup) ((Activity) getContext()).getWindow().getDecorView();
        mAudioProgressLayout = LayoutInflater.from(context).inflate(R.layout.input_layout_audio_recorder_bg, mDecorView, false);
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mAudioProgressLayout.getLayoutParams();
        params.gravity = Gravity.CENTER;
        mAudioProgressLayout.setLayoutParams(params);
        mAudioRecorder = new RecorderUtil(context);
        mAudioRecorder.setRecorderProcessListener(this);
        mAudioProgressView = mAudioProgressLayout.findViewById(R.id.audio_progress);
        audio_cancel_layout = mAudioProgressLayout.findViewById(R.id.audio_cancel_layout);
        audio_send_layout = mAudioProgressLayout.findViewById(R.id.audio_send_layout);
        ScreenAdapterTools.getInstance().loadView(mAudioProgressLayout);
    }

    private float mEventY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (CommonUtils.isFastClick()) return false;
            setText(R.string.string_900128);
            isUpCancel = false;
            mDecorView.addView(mAudioProgressLayout);
            mAudioRecorder.startRecording();
            showRecord(true);
            mEventY = event.getY(0);
            if (onAudioRecorderEventListener != null)
                onAudioRecorderEventListener.onRecorderAudioStart();
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            isUpCancel = Math.abs(event.getY(0) - mEventY) > ScreenAdapterTools.getInstance().loadCustomAttrValue(300);
            showRecord(!isUpCancel);
        } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
            setText(R.string.string_900127);
            stopRecord(isUpCancel ? RESULT_CANCEL : RESULT_OK);
            mDecorView.removeView(mAudioProgressLayout);
        }
        return true;
    }

    @Override
    public void onRecorderProcess(int voiceVolume) {
        mAudioProgressView.setPlayAudiovolume(voiceVolume);
        if (mAudioRecorder.getTimeInterval() >= recorderMaxTime) {
            stopRecord(RESULT_OUT_TIME);
        }
    }

    @Override
    public void onRecorderError() {
        if (onAudioRecorderEventListener != null) {
            onAudioRecorderEventListener.onRecorderAudioEnd(RESULT_TOO_SHORT_ERROR, 0, null);
        }
    }

    /**
     * 显示录音布局
     *
     * @param showSend true显示录音 false显示松开录音
     */
    private void showRecord(boolean showSend) {
        if ((audio_send_layout.getVisibility() == VISIBLE) != showSend) {
            audio_send_layout.setVisibility(showSend ? VISIBLE : GONE);
            audio_cancel_layout.setVisibility(!showSend ? VISIBLE : GONE);
        }
    }

    boolean isUpCancel = false;


    /**
     * 停止录音
     */
    private synchronized void stopRecord(@AudioRecorderView.AudioRecorderResult int result) {
        File file = null;
        if (mAudioRecorder.isRecording()) {
            mAudioRecorder.stopRecording();
            file = new File(mAudioRecorder.getFilePath());
            if (onAudioRecorderEventListener != null) {
                if (mAudioRecorder.getTimeInterval() < recorderMinTime) {
                    onAudioRecorderEventListener.onRecorderAudioEnd(RESULT_TOO_SHORT_ERROR, 0, null);
                } else {
                    onAudioRecorderEventListener.onRecorderAudioEnd(result, mAudioRecorder.getTimeInterval(), file);
                }
            }
        }
    }

    public void setOnAudioRecorderEventListener(OnAudioRecorderEventListener onAudioRecorderEventListener) {
        this.onAudioRecorderEventListener = onAudioRecorderEventListener;
    }

    public interface OnAudioRecorderEventListener {
        /**
         * 开始录音
         */
        void onRecorderAudioStart();

        /**
         * 结束录音
         *
         * @param result
         * @param recorderTime 时间 秒
         * @param audioFile
         */
        void onRecorderAudioEnd(@AudioRecorderView.AudioRecorderResult int result, long recorderTime, File audioFile);
    }
}
